using System;
using System.Threading.Tasks;
using DailyPoetryX.Services;
using DailyPoetryX.Services.Implementations;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Graph;
using Xamarin.Essentials;

namespace DailyPoetryX.ViewModels {
    public class SyncPageViewModel : ViewModelBase {
        /******** 构造函数 ********/

        private ISyncService oneDriveSyncService;

        public SyncPageViewModel(
            OneDriveFavoriteStorage oneDriveFavoriteStorage) {
            oneDriveSyncService = new SyncService(
                SimpleIoc.Default.GetInstance<IFavoriteStorage>(),
                oneDriveFavoriteStorage);
            oneDriveSyncService.StatusChanged += (sender, args) =>
                OneDriveStatus = oneDriveSyncService.Status;
            oneDriveSyncService.RemoteFavoriteStorage.StatusChanged +=
                (sender, args) => OneDriveStatus =
                    oneDriveSyncService.RemoteFavoriteStorage.Status;
        }

        /******** 绑定属性 ********/

        public bool OneDriveSignedIn {
            get => _oneDriveSignedIn;
            set => Set(nameof(OneDriveSignedIn), ref _oneDriveSignedIn, value);
        }

        private bool _oneDriveSignedIn;


        public bool OneDriveLoading {
            get => _oneDriveLoading;
            set => Set(nameof(OneDriveLoading), ref _oneDriveLoading, value);
        }

        private bool _oneDriveLoading;

        public string OneDriveStatus {
            get => _oneDriveStatus;
            set => Set(nameof(OneDriveStatus), ref _oneDriveStatus, value);
        }

        private string _oneDriveStatus;

        public DateTime LastOneDriveSyncTime {
            get => Preferences.Get(LAST_ONEDRIVE_SYNC_TIME_KEY,
                DateTime.MinValue);
            set {
                var oldValue = Preferences.Get(LAST_ONEDRIVE_SYNC_TIME_KEY,
                    DateTime.MinValue);
                if (oldValue == value) {
                    return;
                }

                Preferences.Set(LAST_ONEDRIVE_SYNC_TIME_KEY, value);
                RaisePropertyChanged(nameof(LastOneDriveSyncTime), oldValue,
                    value, false);
            }
        }

        /******** 绑定命令 ********/

        public RelayCommand PageAppearingCommand => _pageAppearingCommand ??
            (_pageAppearingCommand = new RelayCommand(async () => {
                OneDriveLoading = true;
                OneDriveSignedIn = await oneDriveSyncService
                    .RemoteFavoriteStorage.IsSignedInAsync();
                OneDriveLoading = false;
            }));

        private RelayCommand _pageAppearingCommand;

        public RelayCommand OneDriveSignInCommand => _onedriveSignInCommand ??
            (_onedriveSignInCommand = new RelayCommand(async () => {
                OneDriveLoading = true;
                OneDriveSignedIn = await oneDriveSyncService
                    .RemoteFavoriteStorage.SignInAsync();
                OneDriveLoading = false;
            }));

        private RelayCommand _onedriveSignInCommand;

        public RelayCommand OneDriveSignOutCommand => _oneDriveSignOutCommand ??
            (_oneDriveSignOutCommand = new RelayCommand(async () => {
                OneDriveLoading = true;
                await oneDriveSyncService.RemoteFavoriteStorage.SignOutAsync();
                OneDriveSignedIn = false;
                OneDriveLoading = false;
            }));

        private RelayCommand _oneDriveSignOutCommand;

        public RelayCommand OneDriveSyncCommand => _oneDriveSyncCommand ??
            (_oneDriveSyncCommand = new RelayCommand(async () => {
                OneDriveLoading = true;

                var syncResult = await oneDriveSyncService.SyncAsync();
                if (syncResult.Status == ServiceResultStatus.Ok) {
                    LastOneDriveSyncTime = DateTime.Now;
                }

                OneDriveLoading = false;
            }));

        private RelayCommand _oneDriveSyncCommand;

        /******** 私有变量 ********/

        private const string LAST_ONEDRIVE_SYNC_TIME_KEY =
            nameof(SyncPageViewModel) + "." + nameof(LastOneDriveSyncTime);
    }
}